package tools;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;

/**
 * Exemple d'utilisation 
 * Log.sendMessage("info",this.getClass().getName(),"Saving content");		
			
 * @author denoyer
 *
 */
public class Log 
{
	static Log log=null;
	private HashMap<String,ArrayList<Message>> messages;
	private HashSet<String> streams;
	private boolean debug;
	
	public Log()
	{
		messages=new HashMap<String,ArrayList<Message>>();
		streams=new HashSet<String>();
		debug=false;
	}
	
	public static void clear()
	{
		log.clearM();
	}
	
	public void clearM()
	{
		messages=new HashMap<String,ArrayList<Message>>();
	}
	public static void addStream(String stream)
	{
		if (log==null) log=new Log();
		log.addStr(stream);
	}
	
	public static void sendMessage(String stream,String classname,String message)
	{
		if (log==null) log=new Log();
		log.send(stream, classname,message);
	}
	
	public static String getAllMessages(String stream)
	{
		if (log==null) log=new Log();
		return(log.getAllMes(stream));
	}
	
	public static String extractToGNUPLOT(String stream,String[] columns)
	{
		if (log==null) log=new Log();
		return(log.extractToGNU(stream,columns));		
	}
	
	public String extractToGNU(String stream,String[] columns)
	{
		StringBuffer sb=new StringBuffer();
		String[] s=Log.getOnlyMessages(stream);
		HashMap<String,ArrayList<String>> values=new HashMap<String,ArrayList<String>>();
		for(String c:columns) values.put(c,new ArrayList<String>());
		for(String s1:s)
		{
			for(String c:columns)
			{
				if (s1.startsWith("<"+c+">"))
				{
					String s2=s1.substring(c.length()+2);
					s2=s2.substring(0,s2.length()-c.length()-3);
					values.get(c).add(s2);
				}
			}
		}

		for(String c:columns)
		{
			sb.append(c+" ");
		}
		sb.append("\n");
		
		for(int i=0;i<values.get(columns[0]).size();i++)
		{
			for(String c:columns)
			{
				
				if (values.get(c).size()>i)
				{	
					sb.append(values.get(c).get(i));
					sb.append(" ");				
				}
				else
				{	
					sb.append("NaN");
					sb.append(" ");				
				}

			}
			sb.append("\n");
		}
		
		return(sb.toString());
	}
	
	public static String[] getOnlyMessages(String stream)
	{
		if (log==null) log=new Log();
		return(log.getOnlyMes(stream));
	}
	
	public static String getAllMessages()
	{
		if (log==null) log=new Log();
		return(log.getAllMes());
	}
	
	public static String[][] getAllMessages_Table()
	{
		if (log==null) log=new Log();
		return(log.getAllMes_Table());	
	}
	
	public static boolean containsStream(String stream)
	{
		if (log==null) log=new Log();
		return(log.containsStr(stream));		
	}
	
	public static void setDebug(boolean debug)
	{
		if (log==null) log=new Log();
		log.setD(debug);
	}
	
	private String[] getOnlyMes(String stream)
	{
		if (log==null) log=new Log();
		String[] s=new String[messages.get(stream).size()];
		for(int i=0;i<messages.get(stream).size();i++)
			s[i]=messages.get(stream).get(i).message;
		return(s);
	}
	
	private void setD(boolean d)
	{
		this.debug=d;
	}
	
	private boolean containsStr(String stream)
	{
		return(streams.contains(stream));
	}
	
	private void addStr(String stream)
	{
		streams.add(stream);
		if (!messages.containsKey(stream)) messages.put(stream,new ArrayList<Message>());
	}
	
	private void send(String stream,String classname,String message)
	{
		if (!streams.contains(stream)) return;
		if (!messages.containsKey(stream)) messages.put(stream,new ArrayList<Message>());
		
		messages.get(stream).add(new Message(classname,message));
		if (debug)
			System.out.println(message);
	}
	
	private String getAllMes(String stream)
	{
		StringBuffer sb=new StringBuffer();
		for(int i=0;i<messages.get(stream).size();i++)
		{
			Date date=new Date(messages.get(stream).get(i).timestamp);
			sb.append("["+date.toString()+" - "+messages.get(stream).get(i).classname+"] "+messages.get(stream).get(i).message+"\n");
		}
		
		return(sb.toString());
	}
		
	private String[][] getAllMes_Table()
	{
		try
		{
		int nbtotal=0;
		
		ArrayList<String> list=new ArrayList<String>();
		for(String stream:streams)
			nbtotal+=messages.get(stream).size();
		
		String[][] retour=new String[nbtotal][3];
		int nb=0;
		for(String stream:streams)
		{
			for(int i=0;i<messages.get(stream).size();i++)
			{
				Date date=new Date(messages.get(stream).get(i).timestamp);
				retour[nb][0]=date.toString();
				retour[nb][1]=messages.get(stream).get(i).classname;
				retour[nb][2]=messages.get(stream).get(i).message;
				nb++;
			}
		}
		
		return(retour);
		}
		catch(Exception e)
		{
			e.printStackTrace();
		}
		return null;
	}
		
	private String getAllMes()
	{
		StringBuffer sb=new StringBuffer();
		for(String stream:streams)
		{
			sb.append(getAllMes(stream));			
		}
		
		return(sb.toString());
	}
	
	private class Message
	{
		public long timestamp;
		public String classname;
		public String message;
		
		public Message(String classname,String message)
		{
			timestamp=System.currentTimeMillis();
			this.message=message;		
			this.classname=classname;
		}
	}
}
